<template>
  <div class="mapsBox">
    <div class="map" id="map"></div>
    <!-- 弹框 -->
    <MapPopup 
      :position="mapPopupData.position" 
      :title="mapPopupData.title" 
      :offset="mapPopupData.offset" 
      :mapShow.sync="mapShow"  
      :className="'map-popup'"
    >
      <component :is="currentMapPopup" :item="mapPopupData.item"/>
    </MapPopup>
  </div>
</template>

<script>
import Vue from "vue";
import { Map, View, Feature } from "ol";
import TileLayer from "ol/layer/Tile.js";
import { Vector, Image as ImageLayer } from "ol/layer.js";
// import { XYZ, Vector as VectorSource } from "ol/source";
import XYZ from "ol/source/XYZ";
import VectorSource from "ol/source/Vector";
import ImageStatic from "ol/source/ImageStatic";
import { defaults as defaultControls } from "ol/control.js";
import { defaults as defaultInteractions } from "ol/interaction.js";
import LinearRing from "ol/geom/LinearRing.js";
import { fromExtent } from "ol/geom/Polygon";
import GeoJSON from "ol/format/GeoJSON";
import { Style, Stroke, Fill, Icon, Text } from "ol/style";
import { Point, Polygon } from "ol/geom";
import Overlay from "ol/Overlay";
// import Stroke from "ol/style/Stroke";
import { getCenter } from "ol/extent.js";
import "ol-ext/interaction/Synchronize.css";
import Mask from "ol-ext/filter/Mask";
import MapPopup from './MapPopup'
import gdGeoJson from "@/assets/geo-json/gd_geo.json";
import gdBg from "@/assets/map/gd-pro.png";
import spaceAnalysisDialog from './spaceAnalysisDialog.vue'
export default {
    components:{
        MapPopup,spaceAnalysisDialog,
    },
  data() {
    return {
      map: null,
      isDraw: false, // 是否绘制图层
      // http://t4.tianditu.com  改为  http://t4.tianditu.gov.cn  解决天地图底图在部分浏览器无法正常显示问题
      VITE_MAP_IMG: `http://t1.tianditu.gov.cn/img_w/wmts?layer=img&style=default&Service=WMTS&Request=GetTile&Version=1.0.0&Format=tiles&TileMatrix={z}&TileCol={x}&TileRow={y}&transparent=true&TILEMATRIXSET=w`,
      VITE_MAP_ADDRESS: `http://t1.tianditu.gov.cn/cva_w/wmts?layer=cva&style=default&tilematrixset=c&Service=WMTS&Request=GetTile&Version=1.0.0&Format=tiles&TileMatrix={z}&TileCol={x}&TileRow={y}&transparent=true&TILEMATRIXSET=w`,
      VITE_MAP_TK: "9736124e2428673ee2fbe201852e75b0",
      curAdcode: "",
      isPro: true, //是否是省级
      curZoom: 7, //7.5
      gdImageLayer: null,
      GD_IMAGE_LAYER_CLASS: "map-gd-image-layer",
      MARKER_LAYER_CLASS: "map-marker-layer",
      GD_GEO_LAYER_CLASS: "map-gd-geo-layer",
      provinceMaxZoom: 9,
      ADDR_NAME_LAYER_CLASS: "map-address-name-layer",
      geoBgMiddleLayer: null,
      geoBgBottomLayer: null,
      bgMiddleColor: "" || "#1d384c",
      bgBottomColor: "" || "#14283F",
      markerList:[],
      mapPopupData:{
                position: [], // 弹窗中心点 Array[array]， 必须
                title: {}, // 弹窗标题 String，非必须，默认为 ' '
                show: false, // 弹窗显隐 Boolean，必须，默认为 true
                offset:[0, 0], // 弹窗偏移 Array[number]，必须，默认为 [0, 0]
                className: 'map-popup', // 图层的class String，非必须，默认为 'map-popup'
                id:'',
                item:''
            },
      currentMapPopup: '',
      mapShow:false,
    };
  },
  methods:{
      mapPopupClose(){
          this.mapShow = false
      },
      initMap() {
      //https://www.cnblogs.com/yuNotes/p/17710738.html
      const mapTileLayer = new TileLayer({
        //世界地图底图Layer
        className: "worldLayer",
        source: new XYZ({
          url: `${this.VITE_MAP_IMG}&tk=${this.VITE_MAP_TK}`,
          crossOrigin: "anonymous",
        }),
      });
      this.geoLayer = new Vector({
        // 广东省范围Layer
        className: this.GD_GEO_LAYER_CLASS,
        source: new VectorSource(),
        zIndex: 15,
      });
      this.gdImageLayer = new ImageLayer({
        className: this.GD_IMAGE_LAYER_CLASS,
        source: new ImageStatic({
          url: gdBg,
          crossOrigin: "",
          imageExtent: [109.37, 20.0, 117.38, 25.63],
        }),
        zIndex: 9,
      });
      this.markerLayer = new Vector({
        //// 标记层Layer
        className: this.MARKER_LAYER_CLASS,
        source: new VectorSource({
          features: [],
        }),
        // style: function (feature) {
        //   // console.log(222, feature);
        //   return new Style({
        //     image: new Icon({
        //       anchor: [0.5, 1],
        //       src: markerIcon
        //     })
        //   })
        // },
        zIndex: 26,
      });
      // 先不用天地图地点名称标注layer，直接用geo的name来显示地名
      const addrNameLayer = new TileLayer({
        className: this.ADDR_NAME_LAYER_CLASS,
        source: new XYZ({
          url: `${this.VITE_MAP_ADDRESS}&tk=${this.VITE_MAP_TK}`,
        }),
        zIndex: 12,
      });
      // 广东省偏移背景中间层Layer
      this.geoBgMiddleLayer = new Vector({
        className: "bg1",
        source: new VectorSource(),
        zIndex: 6,
      });
      this.geoBgBottomLayer = new Vector({
        className: "bg2",
        source: new VectorSource(),
        zIndex: 5,
      });
      this.originView = new View({
        // 视图
        projection: "EPSG:4326", // 坐标系
        center: getCenter([109.45, 20.09, 117.2, 25.31]),
        // zoom: 7.5, // 默认视图层级
        zoom: this.curZoom, // 默认视图层级
        minZoom: 2, // 设置最小缩放级别
        maxZoom: 22, // 设置最大缩放级别
        multiWorld: true,
      });

      // 文字标注
      // new TileLayer({
      //   className: "worldLayer_city_name",
      //   source: new XYZ({
      //     url: `${this.VITE_MAP_ADDRESS}&tk=${this.VITE_MAP_TK}`,
      //   }),
      //   zIndex: 10,
      // }),
      this.map = new Map({
        target: "map", // 指定挂载dom，注意必须是id
        layers: [
          mapTileLayer,
          this.geoLayer,
          this.markerLayer,
          this.geoBgMiddleLayer,
          this.geoBgBottomLayer,
          this.gdImageLayer,
        ],
        view: this.originView,
        controls: defaultControls({
          attribution: false, // 禁用右下角的地图属性组件
          rotate: false, // 禁用旋转组件 alt+shift true旋转交互时会有一个旋转控件显示出来
          zoom: false, // 禁用右上角缩放组件
        }), // 地图控件
        interactions: defaultInteractions({
          doubleClickZoom: false, // 禁用双击缩放
        }),
      });
      // 蒙层
      const mask = new Mask({
        // feature: new GeoJSON().readFeature(unuseGeoJson?.features?.[0]),
        // feature随便弄个区间,除了这个区间，其他都用蒙版盖住
        feature: new Feature({
          geometry: new Polygon([
            [
              [41.23875891, 46.12191655],
              [41.82794341, 46.16233235],
              [41.482995, 45.83437432],
            ],
          ]),
        }),
        wrapX: true,
        inner: false,
        fill: new Fill({ color: [39, 90, 116, 0.8] }),
      });
      mapTileLayer.addFilter(mask);
      // 绘制经纬度
      // this.map.addInteraction(new Synchronize({ maps: this.map }))
      // 将map保存到全局
      window._map = this.map;
      this.isDraw = true;
      this.initGeoJson();
      this.initMapEvent();
    },
    initMapEvent(){
        this.map.on("click", (e) => {
            let featureAlls = this.map.forEachFeatureAtPixel(e.pixel,
                function (feature, layer) {
                    return feature;
                }
            );
            if(featureAlls){
                let iconTypeName = featureAlls.get('iconTypeName')
                let values = featureAlls.values_
                if(iconTypeName == 'bar'){
                    this.$router.push({
                    // name: 'cityDetailDetail',
                    path:'/public/cityAnalysis/cityDetailDetail',
                    query: {
                        cityCode:values.cityCode,
                        year:values.year,
                        checkType:''
                    },
                    })
                }
            }
        })
        // 鼠标移动事件
        this.map.on("pointermove", (evt) => {
            // console.log('pointermove===')
            if (evt.dragging) {
                return;
            }
            const pixel = this.map.getEventPixel(evt.originalEvent);
            let feature = this.map.forEachFeatureAtPixel(pixel,(feature)=>{
                return feature
            })
            if(feature == undefined || feature.getGeometry().getType() !='bar'){
                this.map.getTargetElement().style.cursor = 'auto'
            }else{
                this.map.getTargetElement().style.cursor = 'pointer'
            }
            console.log('pointermove===',feature)
            if(feature&&feature.values_.iconType == 'spaceAnalysis'){
              let values_ = feature.values_
              this.mapPopupData = JSON.parse(JSON.stringify(values_)) //深拷贝
              this.mapShow = true
              this.mapPopupData.position = [values_.posX,values_.posY]
              this.mapPopupData.item = values_
              this.currentMapPopup = 'spaceAnalysisDialog'
            }else{
                this.mapShow = false
            }
             
        })
    },
    initGeoJson() {
      this.addCityGeoFeature().then(() => {
        // onMapMount();
      });
    },
    async addCityGeoFeature() {
      const features = this.geoLayer.getSource().getFeatures();
      console.log('addCityGeoFeature----', features)
      if (features.length === 0) {
        await this.addGeoFeature("pro", gdGeoJson);
        // console.log('2222====',this.geoLayer.getSource().getFeatures())
      }
    },
    addGeoFeature({ type = "pro" || "city" }, geoJson) {
      this.geoLayer.getSource().clear();
      return new Promise((resolve) => {
        const features = new GeoJSON().readFeatures(geoJson);
        // console.log('features----加载', features)
        features.map((feature, index) => {
          const featureClone = feature.clone();
          // console.log(featureClone)
          const { name } = featureClone.values_ || {};
          // console.log("name====111", name);
          featureClone.setStyle(
            new Style({
              fill: new Fill({
                color: "transparent",
              }),
              stroke: new Stroke({
                color: "transparent",
                width: 1,
              }),
              text: new Text({
                font: "22rem PingFang,sans-serif",
                fill: new Fill({
                  color: "#fff",
                }),
                textAlign: "center",
                justify: "center",
                text: `${name}`,
              }),
            })
          );
          this.geoLayer.getSource().addFeature(featureClone);
          // console.log('2222====333333',this.geoLayer.getSource().getFeatures())
          if (type === "city") {
            this.geoBgMiddleLayer.getSource().addFeature(featureClone.clone());
            this.geoBgBottomLayer.getSource().addFeature(featureClone.clone());
          }
          if (features.length === index + 1) {
            setTimeout(() => {
              resolve({});
            }, 300);
          }
        });
      });
    },
    //渲染撒点
    setMarkers(array) {
      console.log('arr====',array)
      let featureArr = [];
      array.map((item) => {
        const image = new Image();
        image.src = item.icon; // 设置图片源
        image.onload = () => {
          // 当图片加载完成后执行的函数
          const width = image.naturalWidth; // 获取图片的宽度
          const height = image.naturalHeight; // 获取图片的高度
          let feature = new Feature({
            ...item,
            id: item.id || "",
            iconType:  item.iconType || '',
            geometry: new Point([item.posX, item.posY]),
          });
          let text = "";
          if (item.text) {
            text = new Text({
              font: "16px PingFang,sans-serif",
              textAlign: "center",
              justify: "center",
              text: item.text,
              fill: new Fill({
                color: [255, 255, 255, 1],
              }),
              backgroundFill: new Fill({
                color: "#15221F",
              }),
              backgroundStroke: new Stroke({
                color: "#05FFCC",
                width: 1,
              }),
              padding: [0, 4, 0, 6],
              offsetY: -height - 20,
            });
          }
          feature.setStyle(
            new Style({
              image: new Icon({
                src: item.icon,
                scale: item.scales || 0.8, //图标缩放比例
                size: [width, height],
                anchor: [0.5, 1], //图标底部居中
                // rotation: (item.heading * Math.PI) / 180,
              }),
              text: text,
            })
          );
          feature.set('iconTypeName',item.iconTypeName)
          feature.on("click", (e) => {
            console.log("feature===click", e);
          });
          featureArr.push(feature);
          this.markerLayer.getSource().addFeature(feature);
        };
      });
    },
    clearLayer(targetLayer) {
      targetLayer.getSource().clear();
    },

  },
  mounted(){
      this.initMap();
      this.eventBus.$on('clearMap',() => {
        this.mapShow = false
        this.clearLayer(this.markerLayer);
      })
      this.eventBus.$on('setMarkersMaps',(data) => {
          console.log('setMarkersMaps====',data)
        this.mapShow = false
        this.clearLayer(this.markerLayer);
        this.markerList = data
        this.setMarkers(data)
    })
  }
};
</script>

<style lang="scss" scoped>
.mapsBox {
  width: 100%;
  height: 100%;

  #map {
    width: 100%;
    height: 100%;
  }
}
</style>